package integration.deng.spring.userwebapp.services;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * Provide a singleton manager that loads and store expensive resources during
 * integration testing.
 * 
 * @author dengz1
 *
 */
public class IntegerationManager {
	
	public static final String DEFAULT_HIBERNATE_CFG_XML = "integration/hibernate-integration.cfg.xml";
	
	// Singleton manager implementation
	private IntegerationManager() {}
	private static IntegerationManager singletonInstance;	
	public static IntegerationManager getInstance() {
		if (singletonInstance == null) {
			singletonInstance = new IntegerationManager();
		}
		return singletonInstance;
	}
	
	// Load/init hibernate session factory instances
	private Map<String, SessionFactory> sessionFactoryMap = new HashMap<String, SessionFactory>();	
	public SessionFactory getSessionFactory() {
		return getSessionFactory(DEFAULT_HIBERNATE_CFG_XML);
	}
	public SessionFactory getSessionFactory(String hibernateCfgXml) {
		SessionFactory sf = sessionFactoryMap.get(hibernateCfgXml);
		if (sf == null) {
			sf = buildSessionFactory(hibernateCfgXml);
			sessionFactoryMap.put(hibernateCfgXml, sf);
		}
		return sf;
	}
	
	protected SessionFactory buildSessionFactory(String hibernateCfgXml) {
		String name = hibernateCfgXml + ".properties";
		InputStream inStream = getClass().getClassLoader().getResourceAsStream(name);
		Properties props = new Properties();
		try {
			props.load(inStream);
		} catch (IOException e) {
			throw new RuntimeException("Failed to load properties from classpath:" + name, e);
		}
		
		AnnotationConfiguration cfg = new AnnotationConfiguration();
		cfg.setProperties(props);
		cfg.configure(hibernateCfgXml);
		return cfg.buildSessionFactory();
	}
	
}
